import { LcDocument } from '@/types/modules/editor/types/editor.type';

/**
 * 从 JSX 文件内容中解析 LcDocument 元数据
 * 支持 JSDoc 格式的注释解析
 */
export interface ParsedDocumentMeta {
  title?: string;
  description?: string;
  type?: 'Page' | 'Component' | 'Block';
  route?: {
    path?: string;
    name?: string;
    layout?: boolean;
    index?: boolean;
    order?: number;
    noLayout?: boolean;
  };
  width?: number;
  height?: number;
  backgroundColor?: string;
  frames?: string[];
  clients?: string[];
  portal?: boolean;
}

/**
 * 从 JSX 文件内容中解析 JSDoc 格式的 LcDocument 元数据
 * @param content JSX 文件内容
 * @returns 解析出的元数据对象
 */
export function parseDocumentMetaFromJSX(content: string): ParsedDocumentMeta {
  const meta: ParsedDocumentMeta = {};

  // 查找 JSDoc 注释块
  const jsdocMatch = content.match(/\/\*\*([\s\S]*?)\*\//);
  if (!jsdocMatch) {
    return meta;
  }

  const commentContent = jsdocMatch[1];
  const lines = commentContent.split('\n').map((line) => line.trim().replace(/^\*\s?/, ''));

  let currentDescription = '';
  let foundFirstTag = false;

  for (const line of lines) {
    if (!line) continue;

    // 处理 @tag 标签
    if (line.startsWith('@')) {
      foundFirstTag = true;

      if (line.startsWith('@type ')) {
        const type = line.substring(6).trim();
        if (type === 'Page' || type === 'Component' || type === 'Block') {
          meta.type = type;
        }
      } else if (line.startsWith('@route ')) {
        const routePath = line.substring(7).trim();
        meta.route = { path: routePath };
      } else if (line.startsWith('@screen ')) {
        const screenInfo = line.substring(8).trim();
        parseScreenInfo(screenInfo, meta);
      } else if (line.startsWith('@frames ')) {
        const framesStr = line.substring(8).trim();
        meta.frames = framesStr.split(',').map((f) => f.trim());
      } else if (line.startsWith('@clients ')) {
        const clientsStr = line.substring(9).trim();
        meta.clients = clientsStr.split(',').map((c) => c.trim());
      } else if (line.startsWith('@portal ')) {
        const portalStr = line.substring(8).trim();
        meta.portal = portalStr === 'true';
      }
    } else if (!foundFirstTag) {
      // 在遇到第一个 @tag 之前的内容作为标题和描述
      if (!meta.title && line) {
        meta.title = line;
      } else if (meta.title && line) {
        currentDescription += (currentDescription ? ' ' : '') + line;
      }
    }
  }

  if (currentDescription) {
    meta.description = currentDescription;
  }

  return meta;
}

/**
 * 解析屏幕信息字符串
 * 支持格式: "1400x800 #f5f5f5", "1400w", "800h", "#f5f5f5"
 */
function parseScreenInfo(screenInfo: string, meta: ParsedDocumentMeta): void {
  const parts = screenInfo.split(/\s+/);

  for (const part of parts) {
    if (part.includes('x')) {
      // 解析尺寸 "1400x800"
      const [widthStr, heightStr] = part.split('x');
      const width = parseInt(widthStr);
      const height = parseInt(heightStr);
      if (!isNaN(width)) meta.width = width;
      if (!isNaN(height)) meta.height = height;
    } else if (part.endsWith('w')) {
      // 解析宽度 "1400w"
      const width = parseInt(part.slice(0, -1));
      if (!isNaN(width)) meta.width = width;
    } else if (part.endsWith('h')) {
      // 解析高度 "800h"
      const height = parseInt(part.slice(0, -1));
      if (!isNaN(height)) meta.height = height;
    } else if (part.startsWith('#')) {
      // 解析背景色 "#f5f5f5"
      meta.backgroundColor = part;
    }
  }
}

/**
 * 将解析出的元数据应用到 LcDocument 对象
 * @param doc 目标 LcDocument 对象
 * @param meta 解析出的元数据
 * @param strategy 合并策略：'overwrite' - 元数据覆盖现有值, 'merge' - 智能合并, 'fill' - 只填充空值（默认）
 * @returns 更新后的 LcDocument 对象
 */
export function applyMetaToDocument<T extends Partial<LcDocument>>(
  doc: T,
  meta: ParsedDocumentMeta,
  strategy: 'overwrite' | 'merge' | 'fill' = 'fill',
): T {
  const updatedDoc = { ...doc };

  // 定义字段处理函数
  const applyField = <K extends keyof T>(
    field: K,
    metaValue: T[K] | undefined,
    isComplexObject: boolean = false,
  ) => {
    if (metaValue === undefined || metaValue === null) return;

    if (strategy === 'overwrite') {
      // 策略1：直接覆盖
      updatedDoc[field] = metaValue;
    } else if (strategy === 'merge') {
      // 策略2：智能合并
      if (isComplexObject && typeof metaValue === 'object' && typeof updatedDoc[field] === 'object') {
        updatedDoc[field] = { ...updatedDoc[field], ...metaValue };
      } else {
        updatedDoc[field] = metaValue;
      }
    } else {
      // 策略3：只填充空值（默认行为，保持原有逻辑）
      if (!updatedDoc[field] ||
          (Array.isArray(updatedDoc[field]) && (updatedDoc[field] as any[]).length === 0)) {
        updatedDoc[field] = metaValue;
      }
    }
  };

  // 应用各个字段
  applyField('title', meta.title as any);
  applyField('description', meta.description as any);
  applyField('type', meta.type as any);

  // route 特殊处理（复杂对象合并）
  if (meta.route) {
    if (strategy === 'fill' && (!updatedDoc.route || !updatedDoc.route.path)) {
      updatedDoc.route = { ...updatedDoc.route, ...meta.route };
    } else if (strategy === 'overwrite') {
      updatedDoc.route = meta.route;
    } else if (strategy === 'merge') {
      updatedDoc.route = { ...updatedDoc.route, ...meta.route };
    }
  }

  applyField('width', meta.width as any);
  applyField('height', meta.height as any);
  applyField('backgroundColor', meta.backgroundColor as any);

  // 数组字段特殊处理
  if (meta.frames && (strategy === 'overwrite' || !updatedDoc.frames || updatedDoc.frames.length === 0)) {
    updatedDoc.frames = meta.frames as any[];
  }

  if (meta.clients && (strategy === 'overwrite' || !updatedDoc.clients || updatedDoc.clients.length === 0)) {
    updatedDoc.clients = meta.clients as any[];
  }

  // boolean 字段特殊处理
  if (typeof meta.portal === 'boolean') {
    if (strategy === 'overwrite' || typeof updatedDoc.portal === 'undefined') {
      updatedDoc.portal = meta.portal;
    }
  }

  return updatedDoc as T;
}

/**
 * 从 JSX 文件内容中提取文档类名之前的头部内容
 * @param content JSX 文件内容
 * @returns 头部内容和文档类的起始位置
 */
export function extractHeaderContent(content: string): {
  headerContent: string;
  documentClassIndex: number;
} {
  const documentClassIndex = content.search(/class\s+(\w+)\s+extends\s+React\.Component/);
  const headerContent = documentClassIndex > -1 ? content.slice(0, documentClassIndex) : content;

  return {
    headerContent,
    documentClassIndex: documentClassIndex > -1 ? documentClassIndex : content.length,
  };
}
